

#include <WiFi.h>
#include <WiFiClient.h>
#include <WebSocketsClient.h>
#include <ArduinoJson.h>
#include "Freenove_WS2812_Lib_for_ESP32.h"

#define LED_PIN 7   // WS2812B灯带数据线连接到Arduino的6号引脚
#define NUM_LEDS 31  // 灯带上LED的数量
#define CHANNEL		0

Freenove_ESP32_WS2812 strip = Freenove_ESP32_WS2812(NUM_LEDS, LED_PIN, CHANNEL, TYPE_GRB);

const char *ssid = "1708";
const char *password = "12345677";
// const char *host = "192.168.3.5";
const char *host = "utilsapi.schoolzl.com";
const char *port = "8088";
// const char *url = "/webSocket/pjypjd4jes";
// const char *deviceId = "pjypjd4jes";

const char *url = "/webSocket/csqse1vclr";
const char *deviceId = "csqse1vclr";

// const char* baseUrl = "cpapi.hsqcp.top";
const char* baseUrl = "192.168.3.5";
const int basePort = 8088;
const String getUrl = "/c-test/postTest";

// 灯状态 1=开启, 0=关闭
String ledStatus = "0";
int brightness = 10;
int red = 255;
int green = 255;
int blue = 255;

WebSocketsClient webSocket;
void webSocketEvent(WStype_t type, uint8_t *payload, size_t length) {
  if (type == WStype_DISCONNECTED) {
    Serial.println("已断开与WebSocket服务器的连接");
  } else if (type == WStype_CONNECTED) {
    Serial.println("已连接到WebSocket服务器");

    sendMsg();
  } else if (type == WStype_TEXT) {
    Serial.printf("接收到消息: %s\n", payload);
    Serial.printf("\n");
    handleMsg(payload, length);
  } else if (type == WStype_BIN) {
    Serial.printf("接收到WStype_BIN消息: %s\n", payload);
    Serial.printf("\n");
    handleMsg(payload, length);
  } else {
    Serial.print("else信息");
  }
}

void sendMsg() {
  // StaticJsonDocument<200> val;  // 静态 JSON 文档，200 是文档的最大内存大小
  // val["name"] = "John";
  // val["age"] = 30;
  // val["city"] = "New York";
  // char jsonBuffer[256];
  // serializeJson(val, jsonBuffer);
  // // 发送消息到服务器
  // webSocket.sendTXT(jsonBuffer);
}

void handleMsg(uint8_t *payload, size_t length) {
  // 将 uint8_t 数组转换为字符串
  String payloadStr = "";
  for (size_t i = 0; i < length; i++) {
    payloadStr += (char)payload[i];
  }

  // 使用 ArduinoJson 解析字符串
  StaticJsonDocument<200> res;  // 适当调整缓冲区大小
  DeserializationError resError = deserializeJson(res, payloadStr);
  

  if (resError) {
    Serial.print("deserializeJson() failed: ");
    Serial.println(resError.c_str());
    return;
  }

  ///所有的都通过type来做判断处理
  String type = res["type"];
  if(type == "5") {
    ///app发过来的心跳信息
    sendResponseApp(res["to"], res["random"]);
  } else if(type == "99") {
    ///服务端发过来的测试心跳机制
    sendHeartbeatTest();
  } else if(type == "101") {
    ///服务端发过来的心跳机制
    // sendHeartbeat();
  } else {
    String to = res["to"];
    // 判断发送的目标是否本设备ID
    if (to == deviceId) {
      String value = res["value"];

      // 打印提取的数据
      Serial.print("msgType的值: ");
      Serial.print(type);
      Serial.print("value的值: ");
      Serial.print(value);
      Serial.printf("\n");
      if (type == "1") {
        if (value == "0") {
          Serial.print("关灯");
          ///下面的代码是supermini用的
          for (int i = 0; i < NUM_LEDS; i++) {
            strip.setLedColorData(i, 0,0,0);
          }
          ledStatus = value;
          strip.show();
        } else {
          Serial.print("开灯");
          ///下面的代码是supermini用的
          for (int i = 0; i < NUM_LEDS; i++) {
            strip.setLedColorData(i, 255,255,255);
          }
          strip.show();
          ledStatus = value;
        }
      } else if (type == "2") {
        if (value == "0") {
          Serial.print("关马达");
        } else {
          Serial.print("开马达");
        }
      } else if (type == "3") {
        red = res["red"];
        green = res["green"];
        blue = res["blue"];
        u8 m_color[1][3] = { {red, green, blue}};//彩灯颜色数组
        for (int i = 0; i < NUM_LEDS; i++) {
          strip.setLedColorData(i, m_color[0][0], m_color[0][1], m_color[0][2]);
        }
        ledStatus = "1";
        strip.show();
      } else if (type == "4") {
        brightness = res["brightness"];
        
        strip.setBrightness(brightness);
        u8 m_color[1][3] = { {red, green, blue}};//彩灯颜色数组
        for (int i = 0; i < NUM_LEDS; i++) {
          strip.setLedColorData(i, m_color[0][0], m_color[0][1], m_color[0][2]);
        }
        ledStatus = "1";
        strip.show();
      } else {
        // subMitPost();
      }

      ///改变状态后, 立刻将设备当前状态发送出去
      sendHeartbeat();
    }
  }
}

/// 设备在接收到app发送的心跳信息后, 将设备状态反馈给app, 所以这里的type=="6"
void sendResponseApp(String to, String random){
  if(to == deviceId) {
    StaticJsonDocument<200> val;  // 静态 JSON 文档，200 是文档的最大内存大小
    val["to"] = "appManage";
    // type==10表示从设备接收到app发来的心跳机制后, 将设备状态反馈给app, 所以这里的type=="6"
    val["type"] = "6";
    val["deviceId"] = deviceId;
    val["random"] = random;
    val["ledStatus"] = ledStatus;
    val["brightness"] = brightness;
    val["red"] = red;
    val["green"] = green;
    val["blue"] = blue;
    char jsonBuffer[256];
    serializeJson(val, jsonBuffer);
    // 发送消息到服务器
    webSocket.sendTXT(jsonBuffer);
  }
}

void sendHeartbeat(){
  // 设备在接收到心跳机制后, 将设备状态发送出去
    StaticJsonDocument<200> val;  // 静态 JSON 文档，200 是文档的最大内存大小
    val["to"] = "server";
    // type==10表示从设备接收到服务端发来的心跳机制后, 将设备的状态返回到服务端(全体用户)
    val["type"] = "10";
    val["deviceId"] = deviceId;
    val["ledStatus"] = ledStatus;
    val["brightness"] = brightness;
    val["red"] = red;
    val["green"] = green;
    val["blue"] = blue;
    char jsonBuffer[256];
    serializeJson(val, jsonBuffer);
    // 发送消息到服务器
    webSocket.sendTXT(jsonBuffer);
}

void sendHeartbeatTest(){
  // 设备在接收到测试心跳机制后, 将设备状态发送出去
    StaticJsonDocument<200> val;  // 静态 JSON 文档，200 是文档的最大内存大小
    val["to"] = "servertest";
    // type==10表示从设备接收到服务端发来的心跳机制后, 将设备的状态返回到服务端(全体用户)
    val["type"] = "98";
    val["deviceId"] = deviceId;
    char jsonBuffer[256];
    serializeJson(val, jsonBuffer);
    // 发送消息到服务器
    webSocket.sendTXT(jsonBuffer);
}

void subMitPost(){
  Serial.println("开始请求数据");
  
  WiFiClient client;
  if (!client.connect(baseUrl, basePort)) {
    Serial.println("请求失败");
    delay(5000);
    return;
  }

  // Send HTTP request
  Serial.println("Sending HTTP request");
  client.print(String("POST ") + getUrl + " HTTP/1.1\r\n" +
               "Host: " + baseUrl + "\r\n" +
               "Connection: close\r\n\r\n");
  
  // Read HTTP response
  Serial.println("Reading HTTP response");
  while (client.connected()) {
    if (client.available()) {
      String line = client.readStringUntil('\r');
      Serial.print(line);
    }
  }
  
  Serial.println();
  Serial.println("Closing connection");
  client.stop();
  
  // Wait for a while before sending the next request
  delay(5000);
}

void setup() {
  Serial.begin(115200);
  delay(1000);

  strip.begin();
  strip.setBrightness(10);

  // 连接到 WiFi
  Serial.println("Connecting to WiFi");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("WiFi连接成功, IP地址: ");
  Serial.println(WiFi.localIP());

  delay(2000);
  // 设置 WebSocket 事件处理程序
  webSocket.begin(host, 8088, url);  // 8088 是服务器端口
  webSocket.onEvent(webSocketEvent);

  Serial.println("正在连接到WebSocket服务器");

  delay(4000);
  // subMitPost();
}

void loop() {
  webSocket.loop();
}

